package com.example.common.mvi

import androidx.lifecycle.ViewModel // Android ViewModel基类
import androidx.lifecycle.viewModelScope // ViewModel的协程作用域
import kotlinx.coroutines.channels.Channel // 协程通道，用于发送数据
import kotlinx.coroutines.flow.* // Flow相关类
import kotlinx.coroutines.launch // 启动协程

/**
 * MVI架构的基础ViewModel
 * 处理用户意图，管理状态，发送事件
 * @param I Intent类型 - 用户意图
 * @param S ViewState类型 - 视图状态
 * @param R Result类型 - 操作结果
 */
abstract class BaseViewModel<I : MviIntent, S : MviViewState, R : MviResult> : ViewModel() {

    // Intent通道，用于接收用户意图，容量无限制
    private val intentChannel = Channel<I>(Channel.UNLIMITED)
    
    // ViewState状态流，保存当前UI状态
    private val _viewState = MutableStateFlow(initialState()) // 私有可变状态流
    val viewState: StateFlow<S> = _viewState.asStateFlow() // 公开只读状态流
    
    // 单次事件通道，用于发送一次性事件
    private val _singleEvent = Channel<SingleEvent>(Channel.BUFFERED) // 有缓冲的通道
    val singleEvent = _singleEvent.receiveAsFlow() // 转换为Flow供外部订阅

    init {
        // 处理Intent流，在ViewModel初始化时开始监听
        intentChannel.receiveAsFlow() // 将通道转换为Flow
            .onEach { intent -> // 对每个Intent执行处理
                handleIntent(intent) // 调用抽象方法处理Intent
            }
            .launchIn(viewModelScope) // 在ViewModel作用域内启动
    }

    /**
     * 发送Intent到ViewModel
     * 外部调用此方法来触发用户意图
     */
    fun sendIntent(intent: I) {
        viewModelScope.launch { // 在协程中执行
            intentChannel.send(intent) // 发送Intent到通道
        }
    }

    /**
     * 更新ViewState
     * 子类调用此方法来更新UI状态
     */
    protected fun updateState(newState: S) {
        _viewState.value = newState // 更新状态流的值
    }

    /**
     * 发送单次事件
     * 子类调用此方法来发送一次性事件
     */
    protected fun sendEvent(event: SingleEvent) {
        viewModelScope.launch { // 在协程中执行
            _singleEvent.send(event) // 发送事件到通道
        }
    }

    /**
     * 获取当前状态
     * 子类可以调用此方法获取当前的ViewState
     */
    protected fun currentState(): S = _viewState.value

    /**
     * 处理Intent的抽象方法
     * 子类必须实现此方法来处理具体的用户意图
     */
    protected abstract suspend fun handleIntent(intent: I)

    /**
     * 初始状态的抽象方法
     * 子类必须实现此方法来提供初始的ViewState
     */
    protected abstract fun initialState(): S
}